package com.ficoxml.xmlparser;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.logging.log4j.LogManager;
import org.dom4j.Document;
//import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


public class InputdataXmlParser extends GenericUDTF{
	static org.apache.logging.log4j.Logger log = LogManager.getLogger(InputdataXmlParser.class);
	 private PrimitiveObjectInspector stringOI = null;
	 @Override 
	 public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
			List<?> inputFields = argOIs.getAllStructFieldRefs();
			List<String> fieldName = new ArrayList<>();
			List<ObjectInspector> resType = new ArrayList<>();

			for (int j = 0; j < (inputFields.size() - 2); j++) {
				// StructField sf = (StructField) inputFields.get(j);
				fieldName.add("c" + j);
				resType.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
			}
			// 返回分别为列名 和 列类型
			return ObjectInspectorFactory.getStandardStructObjectInspector(fieldName, resType);
		}

        public StructObjectInspector initialize0(ObjectInspector[] objectInspectors) throws UDFArgumentException {
        	System.out.println("initialize初始化");
        	// 异常检测
            if (objectInspectors.length != 3) {
                throw new UDFArgumentException("NameParserGenericUDTF() takes exactly one argument");
            }

            if(objectInspectors[0].getCategory()!=ObjectInspector.Category.PRIMITIVE&&((PrimitiveObjectInspector) objectInspectors[0]).getPrimitiveCategory() != PrimitiveObjectInspector.PrimitiveCategory.STRING) {
                throw new UDFArgumentException("NameParserGenericUDTF() takes a string as a parameter");
            }
        	
            //输入
            stringOI = (PrimitiveObjectInspector) objectInspectors[0];
//            System.out.println("stringOI"+stringOI.toString());
            // 输出
            List<String> fieldNames = new ArrayList<String>(23);
            List<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>(23);
            
            // 输出列名
//            outputField(fieldNames,fieldOIs);
            
            String[] arr = { "XM1GYSJHBTXMSQCS", "XM1GYSJHBTSFZSQCS", "XM1GYSFZHBTSJHSQCS", "idCardByPhone1D",
                    "nameByIdCard1D", "IdCardByPhone7D", "nameByIdCard7D", "XM15TNTYSJHSQCS", "XM15TNTYSFZSQCS",
                    "idCardByPhone30D", "nameByIdCard30D", "idCardByPhone3M", "nameByIdCard3M", "idCardByPhone6M",
                    "nameByIdCard6M", "idCardByPhone12M", "nameByIdCard12M", "lastRejectDays", "idCardByIMEI",
                    "phoneByIMEI", "imeiByIdCard", "imeiByPhone" };
            System.out.println("arr"+arr[1]);
            fieldNames.add("appid");
            fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
            for (int i = 0; i < arr.length; i++) {
            	fieldNames.add(arr[i]);
            	fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
			}
            System.out.println("初始化结束");
            
            // 返回分别为列名 和 列类型
            return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
        }

        @Override
        public void process(Object[] objects) throws HiveException {
        	log.info("开始执行process");
        	System.out.println("执行process");
        	//final String feature = stringOI.getPrimitiveJavaObject(objects[0]).toString();
        	//System.out.println("feature"+feature.toString());
        	//System.out.println("stringOI"+stringOI.toString());
        	if (objects.length < 3) {
        		System.out.println("不符合数据格式!");
			forward(objects);
			return;
		}
        	//xml内容
        	String xml= Objects.toString(objects[0] );
        	System.out.println("xml="+xml.toString());
        	//父节点
        	String tablename =  Objects.toString(objects[1]);
        	System.out.println("tablename="+tablename);
        	//2以后是属性
        	String[] arr= new String[objects.length-2]; 
        	for( int i=2;i<objects.length;i++){
        		arr[i-2] = Objects.toString( objects[i]);
        	} 
            String[] a=geneRow(xml,arr,tablename);
            System.out.println("结果为+"+Arrays.toString(a));
            forward(a);
        }

        public String[] geneRow(String xml,String [] arr,String tablename){
           
            String[] string=readStringXmlOut(xml,tablename,arr);
            return string;
        }
        public  String[] readStringXmlOut(String data, String tablename, String[] arr) {

            Document doc = null;
            // 将字符串转为XML
            try {
                doc = DocumentHelper.parseText(data);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 获取根节点
            Element rootElt = doc.getRootElement(); 
            Iterator iterss = rootElt.elementIterator(tablename);
            String ret[]=new String[arr.length+1];
            System.out.println("arr.length"+arr.length);
            while (iterss.hasNext()) {
                ret[0]=rootElt.attributeValue("AppId");
                Element recordEless = (Element) iterss.next();
                for (int i = 0; i < arr.length; i++) {
                    if(recordEless.attributeValue(arr[i])==""){
                        ret[i+1]="";
                    }else {
                        ret[i+1]=recordEless.attributeValue(arr[i]);
                    }
                }
            }

            return ret;
        }



        /**
         * 解析函数，将json格式字符格式化成多行数据
         * @param feature
         * @return
         */
        public ArrayList<Object[]> parseInputRecord(String feature){
            ArrayList<Object[]> resultList = null;
            try {
                JSONObject json = JSON.parseObject(feature);
                resultList = new ArrayList<Object[]>();
                for (String nameSpace : json.keySet()) {                                           
                            String property_name = nameSpace;      
                            Object[] item = new Object[2];
                            item[0] = property_name;
//                            item[1] = featureJson.get(featureName);
                            resultList.add(item);
                        
                    
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return resultList;
        }
        @Override
        public void close() throws HiveException {

        }

        public static void main(String[] args)  throws Exception{
            InputdataXmlParser mulXmlParser1 =new InputdataXmlParser();
            String xml = "<Application SourceCode=\"newupBank\" AppId=\"jksidhaish011000000sadfasdfjd36023\"><InternalBaseVariable  eventCode=\"CREDIT\" timeStamp=\"1570502012000\" customerRandomNumber=\"16504\" callInterfaceName=\"internalData\" product=\"xiaoXiangYouPin\" />"
                    + "<InternalAppInfoVariable idCardByPhone1D=\"4\" XM1GYSJHBTSFZSQCS=\"3\" IdCardByPhone7D=\"4\" XM1GYSJHBTXMSQCS=\"3\" XM15TNTYSJHSQCS=\"4\" nameByIdCard7D=\"3\" nameByIdCard1D=\"3\" XM1GYSFZHBTSJHSQCS=\"1\" nameByIdCard30D=\"3\" XM15TNTYSFZSQCS=\"3\"/>" +
                    "<InternalListVariable cardNoBlType=\"01\" idCardBlType=\"02\" isPhoneBl=\"03\"/>"+
                    "</Application>";
//            String tablename = "InternalAppInfoVariable";
            String[] arr = { "XM1GYSJHBTXMSQCS", "XM1GYSJHBTSFZSQCS", "XM1GYSFZHBTSJHSQCS", "idCardByPhone1D",
                    "nameByIdCard1D", "IdCardByPhone7D", "nameByIdCard7D", "XM15TNTYSJHSQCS", "XM15TNTYSFZSQCS",
                    "idCardByPhone30D", "nameByIdCard30D", "idCardByPhone3M", "nameByIdCard3M", "idCardByPhone6M",
                    "nameByIdCard6M", "idCardByPhone12M", "nameByIdCard12M", "lastRejectDays", "idCardByIMEI",
                    "phoneByIMEI", "imeiByIdCard", "imeiByPhone" };
            String tablename = "InternalAppInfoVariable";
            	 Object[] obj=new Object[4];
            	 obj[0]=xml;
            	 obj[1]=tablename;
            	 obj[2]="XM1GYSJHBTXMSQCS";
            	 obj[3]="XM1GYSJHBTSFZSQCS";
                mulXmlParser1.process(obj);

                
                
        }


    }